home *** CD-ROM | disk | FTP | other *** search
/ Skunkware 5 / Skunkware 5.iso / src / X11 / xmcd-1.4 / libdi.d / os_frbsd.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-05-10  |  5.6 KB  |  264 lines

  1. /*
  2.  *   libdi - CD Audio Player Device Interface Library
  3.  *
  4.  *   Copyright (C) 1995  Ti Kan
  5.  *   E-mail: ti@amb.org
  6.  *
  7.  *   This program is free software; you can redistribute it and/or modify
  8.  *   it under the terms of the GNU General Public License as published by
  9.  *   the Free Software Foundation; either version 2 of the License, or
  10.  *   (at your option) any later version.
  11.  *
  12.  *   This program is distributed in the hope that it will be useful,
  13.  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
  14.  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15.  *   GNU General Public License for more details.
  16.  *
  17.  *   You should have received a copy of the GNU General Public License
  18.  *   along with this program; if not, write to the Free Software
  19.  *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  20.  */
  21.  
  22. /*
  23.  *   FreeBSD support
  24.  *
  25.  *   Contributing author: Gennady B. Sorokopud
  26.  *   E-Mail: gena@netvision.net.il
  27.  *
  28.  *   This software fragment contains code that interfaces the CD player
  29.  *   application to the FreeBSD (version 2.1 or later) operating system.
  30.  */
  31. #ifndef LINT
  32. static char *_os_frbsd_c_ident_ = "@(#)os_frbsd.c    5.3 95/02/16";
  33. #endif
  34.  
  35. #include "common.d/appenv.h"
  36. #include "common.d/util.h"
  37. #include "libdi.d/libdi.h"
  38. #include "libdi.d/scsipt.h"
  39.  
  40. #if defined(__FreeBSD__) && defined(DI_SCSIPT) && !defined(DEMO_ONLY)
  41.  
  42. extern appdata_t    app_data;
  43. extern bool_t        scsipt_notrom_error;
  44. extern FILE        *errfp;
  45.  
  46. STATIC int        pthru_fd = -1;    /* Passthrough device file desc */
  47.  
  48.  
  49. /*
  50.  * pthru_send
  51.  *    Build SCSI CDB and send command to the device.
  52.  *
  53.  * Args:
  54.  *    opcode - SCSI command opcode
  55.  *    addr - The "address" portion of the SCSI CDB
  56.  *    buf - Pointer to data buffer
  57.  *    size - Number of bytes to transfer
  58.  *    rsvd - The "reserved" portion of the SCSI CDB
  59.  *    length - The "length" portion of the SCSI CDB
  60.  *    param - The "param" portion of the SCSI CDB
  61.  *    control - The "control" portion of the SCSI CDB
  62.  *    rw - Data transfer direction flag (READ_OP or WRITE_OP)
  63.  *    prnerr - Whether an error message should be displayed
  64.  *         when a command fails
  65.  *
  66.  * Return:
  67.  *    TRUE - command completed successfully
  68.  *    FALSE - command failed
  69.  */
  70. bool_t
  71. pthru_send(
  72.     byte_t        opcode,
  73.     word32_t    addr,
  74.     byte_t        *buf,
  75.     word32_t    size,
  76.     byte_t        rsvd,
  77.     word32_t    length,
  78.     byte_t        param,
  79.     byte_t        control,
  80.     byte_t        rw,
  81.     bool_t        prnerr
  82. )
  83. {
  84.     static struct scsireq    ucmd;
  85.     
  86.     if (pthru_fd < 0 || scsipt_notrom_error)
  87.         return FALSE;
  88.  
  89.     memset(&ucmd, 0, sizeof(ucmd));
  90.  
  91.     /* set up SCSI CDB */
  92.     switch (opcode & 0xf0) {
  93.     case 0xa0:
  94.     case 0xe0:
  95.         /* 12-byte commands */
  96.         ucmd.cmd[0] = opcode;
  97.         ucmd.cmd[1] = param;
  98.         ucmd.cmd[2] = (addr >> 24) & 0xff;
  99.         ucmd.cmd[3] = (addr >> 16) & 0xff;
  100.         ucmd.cmd[4] = (addr >> 8) & 0xff;
  101.         ucmd.cmd[5] = (addr & 0xff);
  102.         ucmd.cmd[6] = (length >> 24) & 0xff;
  103.         ucmd.cmd[7] = (length >> 16) & 0xff;
  104.         ucmd.cmd[8] = (length >> 8) & 0xff;
  105.         ucmd.cmd[9] = length & 0xff;
  106.         ucmd.cmd[10] = rsvd;
  107.         ucmd.cmd[11] = control;
  108.  
  109.         ucmd.cmdlen = 12;
  110.         break;
  111.  
  112.     case 0xc0:
  113.     case 0xd0:
  114.     case 0x20:
  115.     case 0x30:
  116.     case 0x40:
  117.         /* 10-byte commands */
  118.         ucmd.cmd[0] = opcode;
  119.         ucmd.cmd[1] = param;
  120.         ucmd.cmd[2] = (addr >> 24) & 0xff;
  121.         ucmd.cmd[3] = (addr >> 16) & 0xff;
  122.         ucmd.cmd[4] = (addr >> 8) & 0xff;
  123.         ucmd.cmd[5] = addr & 0xff;
  124.         ucmd.cmd[6] = rsvd;
  125.         ucmd.cmd[7] = (length >> 8) & 0xff;
  126.         ucmd.cmd[8] = length & 0xff;
  127.         ucmd.cmd[9] = control;
  128.  
  129.         ucmd.cmdlen = 10;
  130.         break;
  131.  
  132.     case 0x00:
  133.     case 0x10:
  134.         /* 6-byte commands */
  135.         ucmd.cmd[0] = opcode;
  136.         ucmd.cmd[1] = param;
  137.         ucmd.cmd[2] = (addr >> 8) & 0xff;
  138.         ucmd.cmd[3] = addr & 0xff;
  139.         ucmd.cmd[4] = length & 0xff;
  140.         ucmd.cmd[5] = control;
  141.  
  142.         ucmd.cmdlen = 6;
  143.         break;
  144.  
  145.     default:
  146.         if (app_data.scsierr_msg && prnerr)
  147.             fprintf(errfp, "0x%02x: Unknown SCSI opcode\n",
  148.                 opcode);
  149.         return FALSE;
  150.     }
  151.  
  152.     DBGDUMP("SCSI CDB bytes", ucmd.cmd, ucmd.cmdlen);
  153.         
  154.     /* set up uscsi_cmd */
  155.     ucmd.databuf = (caddr_t) buf; /* data buffer */
  156.     ucmd.datalen = size;    /* buffer length */
  157.     ucmd.timeout = 2000;    /* 2 sec timeout */
  158.  
  159.     if (size != 0)
  160.         ucmd.flags |= (rw == READ_OP) ? SCCMD_READ : SCCMD_WRITE;
  161.  
  162.     /* Send the command down via the "pass-through" interface */
  163.     if (ioctl(pthru_fd, SCIOCCOMMAND, &ucmd) < 0) {
  164.         if (app_data.scsierr_msg && prnerr)
  165.             perror("SCIOCCOMMAND ioctl failed");
  166.         return FALSE;
  167.     }
  168.  
  169.     if (ucmd.retsts != SCCMD_OK) {
  170.         if (app_data.scsierr_msg && prnerr) {
  171.             fprintf(errfp,
  172.                 "CD audio: %s %s:\n%s=0x%x %s=0x%x\n",
  173.                 "SCSI command fault on",
  174.                 app_data.device,
  175.                 "Opcode",
  176.                 opcode,
  177.                 "Status",
  178.                 ucmd.retsts);
  179.         }
  180.  
  181.         return FALSE;
  182.     }
  183.  
  184.     return TRUE;
  185. }
  186.  
  187.  
  188. /*
  189.  * pthru_open
  190.  *    Open SCSI pass-through device
  191.  *
  192.  * Args:
  193.  *    path - device path name string
  194.  *
  195.  * Return:
  196.  *    TRUE - open successful
  197.  *    FALSE - open failed
  198.  */
  199. bool_t
  200. pthru_open(char *path)
  201. {
  202.     struct stat    stbuf;
  203.     char        errstr[ERR_BUF_SZ];
  204.  
  205.     /* Check for validity of device node */
  206.     if (stat(path, &stbuf) < 0) {
  207.         sprintf(errstr, app_data.str_staterr, path);
  208.         cd_fatal_popup(app_data.str_fatal, errstr);
  209.         return FALSE;
  210.     }
  211.     if (!S_ISCHR(stbuf.st_mode)) {
  212.         sprintf(errstr, app_data.str_noderr, path);
  213.         cd_fatal_popup(app_data.str_fatal, errstr);
  214.         return FALSE;
  215.     }
  216.  
  217.     if ((pthru_fd = open(path, O_RDONLY)) < 0) {
  218.         DBGPRN(errfp, "Cannot open %s: errno=%d\n", path, errno);
  219.         return FALSE;
  220.     }
  221.  
  222.     return TRUE;
  223. }
  224.  
  225.  
  226. /*
  227.  * pthru_close
  228.  *    Close SCSI pass-through device
  229.  *
  230.  * Args:
  231.  *    Nothing.
  232.  *
  233.  * Return:
  234.  *    Nothing.
  235.  */
  236. void
  237. pthru_close(void)
  238. {
  239.     if (pthru_fd >= 0) {
  240.         close(pthru_fd);
  241.         pthru_fd = -1;
  242.     }
  243. }
  244.  
  245.  
  246. /*
  247.  * pthru_vers
  248.  *    Return OS Interface Module version string
  249.  *
  250.  * Args:
  251.  *    Nothing.
  252.  *
  253.  * Return:
  254.  *    Module version text string.
  255.  */
  256. char *
  257. pthru_vers(void)
  258. {
  259.     return ("OS Interface module (for FreeBSD)\n");
  260. }
  261.  
  262. #endif    /* __FreeBSD__ DI_SCSIPT DEMO_ONLY */
  263.  
  264.